/**
 * @FileDescription 战时标绘 地图相关操作
 * @Author 祝小文
 * @Date 2022-11-23 10:35
 */

const mapFactorFefaultHeight = 0.5 //地图要素距离地面默认高度

import {
  loadWarAllMapFactor,
  removeTempMapFactor,
  removeLastMapFactorActive,
  removeActiveMapFactor,
} from '@/utils'
import redCircle from '@/assets/image/mapIcon/redCircle.png'
import { insertUpdateMarkerInfo } from '@/service'
import { requireImage } from './vue'
import { ElMessage } from 'element-plus'

const firefightPlotStore: any = useFirefightPlotStore()
const dom = document.getElementById('cesiumContainer')

/** 地图要素点击监听事件 */
export function warLoadFeatureClick() {
  const viewer = window.map3DControl.viewer
  viewer.screenSpaceEventHandler.setInputAction(function (event: any) {
    let cartesian
    //判断是否在模型上
    const pickedObject = viewer.scene.pick(event.position)
    if (Cesium.defined(pickedObject)) {
      //在模型上
      console.log('模型上')
      cartesian = viewer.scene.pickPosition(event.position)
    } else {
      //在模型外
      console.log('模型外')
      const ray = viewer.camera.getPickRay(event.position)
      cartesian = viewer.scene.globe.pick(ray, viewer.scene)
    }
    //如果没拾取到位置/ 没拾取到要素 / 要素为临时要素 / 未进入到作战标绘页面 直接返回
    if (
      !cartesian ||
      !pickedObject?.id ||
      !pickedObject?.id.attribute ||
      pickedObject?.id.attribute.name === 'temp' ||
      !firefightPlotStore.isFirefightPlotFlag
    ) {
      return
    }

    const attribute = pickedObject?.id.attribute
    console.log(attribute)

    //面板属性赋值
    firefightPlotStore.attribute.id = attribute.name
    firefightPlotStore.attribute.zj = attribute.zj
    firefightPlotStore.attribute.name = attribute.bzmc
    firefightPlotStore.attribute.rotate = attribute.rotation
    firefightPlotStore.attribute.radius = attribute.radius
    firefightPlotStore.attribute.bzlx = attribute.bzlx
    firefightPlotStore.attribute.lng = attribute.position.lng
    firefightPlotStore.attribute.lat = attribute.position.lat
    firefightPlotStore.attribute.alt = attribute.position.alt || attribute.position[0].alt
    firefightPlotStore.attribute.bz = attribute?.bz || undefined
    firefightPlotStore.attribute.wzxx = attribute.position

    firefightPlotStore.attribute.zxjd = attribute?.zxdjdwd?.lng
    firefightPlotStore.attribute.zxwd = attribute?.zxdjdwd?.lat
    firefightPlotStore.attribute.zxgd = attribute?.zxdjdwd?.alt

    firefightPlotStore.isLeftPropertyEditFlag = true

    removeTempMapFactor('temp') //移除临时地图要素

    removeLastMapFactorActive() //移除上一次要素选中效果

    firefightPlotStore.activeMapFactor.bzlx = attribute.bzlx
    firefightPlotStore.activeMapFactor.name = attribute.name

    //添加要素选中效果
    //---------- 1. 圆 ----------
    if (firefightPlotStore.bzlxWarCircle.includes(attribute.bzlx)) {
      window.GWarCircle.setActive(attribute.name, true)
    }

    //---------- 2. 文字 ----------
    else if (firefightPlotStore.bzlxWarStickLabel.includes(attribute.bzlx)) {
      window.GWarStickLabel.setActive(attribute.name, true)
    }

    //---------- 3. 标牌 ----------
    else if (firefightPlotStore.bzlxWarSign.includes(attribute.bzlx)) {
      window.GWarSign.setActive(attribute.name, true)
    }

    //---------- 4. 消防车标牌 ----------
    else if (firefightPlotStore.bzlxWarCar.includes(attribute.bzlx)) {
      window.GWarCar.setActive(attribute.name, true)
    }

    //---------- 5. 线 ----------
    else if (firefightPlotStore.bzlxWarPolyline.includes(attribute.bzlx)) {
      window.GWarPolyline.setActive(attribute.name, true)
    }

    //---------- 6. 多边形 ----------
    else if (firefightPlotStore.bzlxWarPolygon.includes(attribute.bzlx)) {
      window.GWarPolygon.setActive(attribute.name, true)
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

/** 地图要素创建 */
export function warFeatureClick(obj: any) {
  //鼠标变成加号 颜色为红色
  if (dom) {
    dom.style.cursor = `url('${requireImage('common/red_cross.png')}') 16 16, crosshair`
  }

  //记录当前标注要素类型
  firefightPlotStore.attribute.bzlx = obj.bzlx

  //多边形和线 需要绘制多个点 走另外一个方法
  if (
    firefightPlotStore.bzlxWarPolyline.includes(obj.bzlx) ||
    firefightPlotStore.bzlxWarPolygon.includes(obj.bzlx)
  ) {
    rightClickProcess(obj)
  } else {
    leftClickProcess(obj)
  }
}

/** 左击结束绘制过程 */
function leftClickProcess(obj: any) {
  const viewer = window.map3DControl.viewer
  viewer.screenSpaceEventHandler.setInputAction(function (event: any) {
    let cartesian
    //判断是否在模型上
    const pickedObject = viewer.scene.pick(event.position)
    if (Cesium.defined(pickedObject)) {
      //在模型上
      console.log('模型上')
      cartesian = viewer.scene.pickPosition(event.position)
    } else {
      //在模型外
      console.log('模型外')
      const ray = viewer.camera.getPickRay(event.position)
      cartesian = viewer.scene.globe.pick(ray, viewer.scene)
    }
    //如果没拾取到位置直接返回
    if (!cartesian) {
      return
    }
    // 打开属性设置面板
    firefightPlotStore.isLeftPropertyEditFlag = true
    // 关闭标绘属性提示
    useChemicalStore().tipsPageShow = false
    //鼠标变成默认
    if (dom) {
      dom.style.cursor = 'default'
    }

    //笛卡尔转经纬度
    const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
    const lng = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    const alt = cartographic.height + mapFactorFefaultHeight

    //临时地图要素上图
    const option = {
      id: 'temp',
      cjid: 'temp',
      bzlx: obj.bzlx,
      wzxx: window.cesiumMapTool.WGS84ToCar3({ lng, lat, alt }),
      zj: obj.label,
      bzmc: obj.text,
    }

    //标牌
    if (firefightPlotStore.bzlxWarSign.includes(obj.bzlx)) {
      option.bzmc = obj.label
      firefightPlotStore.attribute.name = obj.label
    }

    //消防车标牌
    if (firefightPlotStore.bzlxWarCar.includes(obj.bzlx)) {
      option.zj = obj.text
      option.bzmc = obj.label
    }

    loadWarAllMapFactor([option])

    //默认注记回填
    const defaultZj = ['12']
    if (defaultZj.includes(obj.bzlx)) {
      firefightPlotStore.attribute.zj = obj.label
    }

    //保存当前经纬度信息
    firefightPlotStore.attribute.lng = lng
    firefightPlotStore.attribute.lat = lat
    firefightPlotStore.attribute.alt = alt

    clearWarEditState() //清除标注状态

    warLoadFeatureClick() //监听要素点击事件
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

/** 右击结束绘制过程 */
function rightClickProcess(obj: any) {
  const viewer = window.map3DControl.viewer
  const pointArr: any = []
  const dkePointArr: any = []
  const cloneDkePointArr: any = []
  viewer.screenSpaceEventHandler.setInputAction(function (event: any) {
    let cartesian
    // 判断是否在模型上绘制
    const pickedObject = viewer.scene.pick(event.position)
    if (Cesium.defined(pickedObject)) {
      //在模型上
      cartesian = window.map3DControl.viewer.scene.pickPosition(event.position)
    } else {
      //在模型外
      const ray = viewer.camera.getPickRay(event.position)
      cartesian = viewer.scene.globe.pick(ray, viewer.scene)
    }
    //如果没拾取到位置直接返回
    if (!cartesian) {
      return
    }

    //笛卡尔坐标转经纬度坐标
    const ellipsoid = viewer.scene.globe.ellipsoid
    const cartographic = ellipsoid.cartesianToCartographic(cartesian)
    const lng = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    const alt = cartographic.height + mapFactorFefaultHeight
    pointArr.push({ lng, lat, alt })

    dkePointArr.push(window.cesiumMapTool.WGS84ToCar3({ lng, lat, alt }))
    cloneDkePointArr.push(window.cesiumMapTool.WGS84ToCar3({ lng, lat, alt }))

    //辅助点
    window.GPoint.add({
      parentName: 'tempPoint',
      option: {
        position: [lng, lat, alt],
        scale: 0.1,
        url: redCircle,
        pixelOffset: [0, 0],
      },
    })

    //线
    if (firefightPlotStore.bzlxWarPolyline.includes(obj.bzlx)) {
      //进攻方向
      if (obj.bzlx === '18') {
        if (dkePointArr.length >= 2 && dkePointArr.length < 3) {
          loadWarAllMapFactor([
            {
              id: 'temp',
              cjid: 'temp',
              bzlx: obj.bzlx,
              wzxx: dkePointArr,
            },
          ])

          //打开属性设置面板
          firefightPlotStore.isLeftPropertyEditFlag = true

          //保存当前经纬度信息
          firefightPlotStore.attribute.wzxx = pointArr

          //保存中心点经度纬度
          const cenPos = calCulatePosCenter(pointArr)
          firefightPlotStore.attribute.zxjd = cenPos[0]
          firefightPlotStore.attribute.zxwd = cenPos[1]
          firefightPlotStore.attribute.zxgd = cenPos[2]

          clearWarEditState() //清除标绘状态

          warLoadFeatureClick() //监听要素点击事件
        }
      }
      //折线
      else if (dkePointArr.length >= 2 && dkePointArr.length < 3) {
        loadWarAllMapFactor([
          {
            id: 'temp',
            cjid: 'temp',
            bzlx: obj.bzlx,
            zj: obj.label,
            wzxx: dkePointArr,
          },
        ])
      } else if (dkePointArr.length >= 3) {
        //重新设置线的位置
        window.GWarPolyline.setPosition('temp', dkePointArr)
      }
    }

    //多边形
    else if (firefightPlotStore.bzlxWarPolygon.includes(obj.bzlx)) {
      if (dkePointArr.length >= 3 && dkePointArr.length < 4) {
        loadWarAllMapFactor([
          {
            id: 'temp',
            cjid: 'temp',
            bzlx: obj.bzlx,
            zj: obj.label,
            wzxx: dkePointArr,
            zxdjdwd: window.cesiumMapTool.getPolygonCenter(dkePointArr),
          },
        ])
      } else if (dkePointArr.length >= 4) {
        //修改体的标注中心点位置信息
        window.GWarPolygon.setLabelPosition(
          'temp',
          window.cesiumMapTool.getPolygonCenter(cloneDkePointArr)
        )
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

  viewer.screenSpaceEventHandler.setInputAction(function () {
    //保存当前经纬度信息
    firefightPlotStore.attribute.wzxx = pointArr

    //默认注记回填
    const defaultZj = ['22', '23', '24', '26', '27']
    if (defaultZj.includes(obj.bzlx)) {
      firefightPlotStore.attribute.zj = obj.label
    }

    //保存中心点经度纬度
    const cenPos = calCulatePosCenter(pointArr)
    firefightPlotStore.attribute.zxjd = cenPos[0]
    firefightPlotStore.attribute.zxwd = cenPos[1]
    firefightPlotStore.attribute.zxgd = cenPos[2]

    //鼠标变成默认
    if (dom) {
      dom.style.cursor = 'default'
    }

    //打开属性设置面板
    firefightPlotStore.isLeftPropertyEditFlag = true

    //移除辅助点
    window.GPoint.removeByPatName('tempPoint')

    clearWarEditState() //清除标绘状态

    warLoadFeatureClick() //监听要素点击事件
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}

/** 清除标注状态 */
export function clearWarEditState() {
  const viewer = window.map3DControl.viewer

  useChemicalStore().tipsPageShow = false // 关闭标绘提示

  window.GPoint.removeByPatName('tempPoint') //移除辅助点

  removeLastMapFactorActive() //移除上一次要素选中效果

  //鼠标变成默认
  if (dom) {
    dom.style.cursor = 'default'
  }

  //移除地图点击事件
  viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
  viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}

/** 通过标注类型 设置新增要素的属性 */
export function setAttrInfo(name: any, bzlx: any, position: any, rotation: any) {
  //---------- 1. 修改经纬度高度 ----------
  if (position) {
    let dkePosition
    if (position instanceof Array) {
      dkePosition = position.map((item: any) => window.cesiumMapTool.WGS84ToCar3(item))
    } else if (position instanceof Object) {
      dkePosition = window.cesiumMapTool.WGS84ToCar3(position)
    }

    //圆
    if (firefightPlotStore.bzlxWarCircle.includes(bzlx)) {
      window.GWarCircle.setPosition(name, dkePosition)
    }

    //文字
    else if (firefightPlotStore.bzlxWarStickLabel.includes(bzlx)) {
      window.GWarStickLabel.setPosition(name, dkePosition)
    }

    //标牌
    else if (firefightPlotStore.bzlxWarSign.includes(bzlx)) {
      window.GWarSign.setPosition(name, dkePosition)
    }

    //消防车标牌
    else if (firefightPlotStore.bzlxWarCar.includes(bzlx)) {
      window.GWarCar.setPosition(name, dkePosition)
    }

    //线
    else if (firefightPlotStore.bzlxWarPolyline.includes(bzlx)) {
      window.GWarPolyline.setPosition(name, dkePosition, true)
    }

    //多边形
    else if (firefightPlotStore.bzlxWarPolygon.includes(bzlx)) {
      window.GWarPolygon.setPosition(name, dkePosition)
    }
  }

  //---------- 2. 修改旋转角度 ----------
  if (rotation !== null) {
    //文字
    if (firefightPlotStore.bzlxWarStickLabel.includes(bzlx)) {
      window.GWarStickLabel.setRotation(name, rotation)
    }
    //标牌
    else if (firefightPlotStore.bzlxWarSign.includes(bzlx)) {
      window.GWarSign.setRotation(name, rotation)
    }
    //消防车标牌
    else if (firefightPlotStore.bzlxWarCar.includes(bzlx)) {
      window.GWarCar.setRotation(name, rotation)
    }
  }
}

/** 保存地图要素信息 */
export function saveMapFactorInfo() {
  const factorInfo: any = firefightPlotStore.attribute

  const params: any = {
    id: factorInfo.id,
    qyid: useChemicalStore().qyInfo.id,
    cjid: firefightPlotStore.currentCheckLayerList[0].id,
    bzlx: factorInfo.bzlx,
    zj: factorInfo.zj,
    bzmc: factorInfo.name,
    wzxx: JSON.stringify(factorInfo.wzxx),
    zxjd: factorInfo.zxjd,
    zxwd: factorInfo.zxwd,
    zxgd: factorInfo.zxgd,
    sfyx: 1,
  }

  //如果是修改，移除上一次的要素
  if (params.id) {
    removeLastMapFactorActive() //移除上一次要素选中效果
    removeActiveMapFactor(factorInfo.bzlx, params.id)
  }

  //---------- 圆 ----------
  if (firefightPlotStore.bzlxWarCircle.includes(factorInfo.bzlx)) {
    params.bj = factorInfo.radius
  }

  //---------- 标牌 / 消防车标牌 / 文字 ----------
  else if (
    firefightPlotStore.bzlxWarSign.includes(factorInfo.bzlx) ||
    firefightPlotStore.bzlxWarCar.includes(factorInfo.bzlx) ||
    firefightPlotStore.bzlxWarStickLabel.includes(factorInfo.bzlx)
  ) {
    params.xzjd = factorInfo.rotate
  }

  console.log(params)

  //保存
  insertUpdateMarkerInfo(params)
    .then((res: any) => {
      console.log(res)
      removeTempMapFactor('temp') //移除临时地图要素
      loadWarAllMapFactor([res]) //用后台返回数据重新创建
      firefightPlotStore.isLeftPropertyEditFlag = false
      ElMessage.success('保存标绘要素成功')
    })
    .catch((err) => {
      ElMessage.error('保存标绘要素失败')
    })
}

export const deleteEssentialFactor = () => {
  const firefightPlotStore: any = useFirefightPlotStore()
  const factorInfo: any = firefightPlotStore.attribute
  const params = {
    id: factorInfo.id,
    qyid: useChemicalStore().qyInfo.id,
    cjid: firefightPlotStore.currentCheckLayerList[0].id,
    bzlx: factorInfo.bzlx,
    zj: factorInfo.zj,
    bzmc: factorInfo.name,
    wzxx: JSON.stringify(factorInfo.wzxx),
    zxjd: factorInfo.zxjd,
    zxwd: factorInfo.zxwd,
    zxgd: factorInfo.zxgd,
    sfyx: 0,
  }
  //删除
  insertUpdateMarkerInfo(params)
    .then((res: any) => {
      removeActiveMapFactor(factorInfo.bzlx, factorInfo.id)
      firefightPlotStore.isLeftPropertyEditFlag = false
      ElMessage.success('删除标绘要素成功')
    })
    .catch((err) => {
      ElMessage.error('删除标绘要素失败')
    })
}

/** 传入经纬度计算中心点 */
function calCulatePosCenter(pos: any) {
  let xAxios = 0,
    yAxios = 0,
    zAxios = 0,
    cenPos
  pos.forEach((item: any) => {
    xAxios += item.lng
    yAxios += item.lat
    zAxios += item.alt
  })
  cenPos = [xAxios / pos.length, yAxios / pos.length, zAxios / pos.length]
  return cenPos
}
